#include "fxcc/imgui/Editor.h"
#include "fxcc/core/graph/common/MaterialView.h"
#include "fxcc/core/graph/common/ModelImporter.h"
#include "fxcc/core/graph/common/ShaderLoader.h"

using namespace fxcc::graph::common;
using namespace fxcc::imgui;

template<>
bool Editor::Edit<fxcc::graph::common::EffectToken>(const std::string& l, fxcc::graph::common::EffectToken& e)
{
	int index = 0;;
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Key.c_str(), 0);

	if (combo)
	{
		for (const auto& [key, value] : ShaderLoader::m_Effects)
		{
			bool selectable = ImGui::Selectable(key.c_str(), key == e.m_Key);

			if (selectable)
			{
				e.m_Key = key;
				flag = true;
			}
		}
	}

	if (combo)
	{
		ImGui::EndCombo();
	}
	if (ImGui::BeginDragDropTarget()) {
		if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("EffectToken")) {
			using T = EffectToken;
			const T* effect = (const T*)payload->Data;

			e.m_Key = effect->m_Key;
			flag = true;
		}
		ImGui::EndDragDropTarget();
	}

	return flag;
}


template<>
bool Editor::Edit<fxcc::graph::common::MaterialNativeDataMap>(const std::string& l, fxcc::graph::common::MaterialNativeDataMap& e)
{
	bool flag{ 0 };

	bool combo = ImGui::BeginCombo(l.c_str(), e.m_Index.m_Name.c_str());

	if (combo)
	{

		for (const auto& [key, value] : ModelImporter::m_ModelMetaData.m_ModelMetaCache)
		{
			ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.5f, 1.0f, 0.5f, 1.0f));
			ImGui::Text(key.c_str());
			ImGui::PopStyleColor();

			for (const auto& value2 : value.m_MaterialMetaIndexes)
			{
				ImGui::PushID(&value2);
				const std::string& itemLabel = value2.m_Name;
				bool selectable = ImGui::Selectable(itemLabel.c_str(), e.m_Index.m_FileId == value2.m_FileId);
				if (selectable && e.m_Index != value2)
				{
					e.m_Index = value2;
					flag = true;
				}
				ImGui::PopID();
			}
		}
		ImGui::EndCombo();
	}

	if (flag)
	{
		ztclog::info("material native data init");
		e.OnLoad();
	}
	return flag;

}

template <>
bool Editor::Edit<MaterialView>(const std::string& label, MaterialView& inst)
{
	ImGui::Text("%s", label.c_str());

	int index = 0;

    bool flag{ 0 };
	bool _shader_changed_{ 0 };

    flag |= EditInst<MaterialNativeDataMap>("m_NativeDataMap", inst.m_NativeDataMap);
	flag |= EditInst<EffectToken>("m_EffectToken", inst.m_EffectToken);

	if (flag)
	{
		inst.OnShaderChanged();
	}

	if (inst.m_NativeDataMap.m_Value)
	{
		if (TreeNode("Native Data", inst.m_ImguiFlag, index++))
		{
			EditInst<fxcc::graph::common::MaterialData>("m_NativeData", *inst.m_NativeDataMap.m_Value);
			TreePop();
		}
	}

    flag |= EditInst<fxcc::graph::common::Params>("m_Params_", inst.m_Params);
    flag |= EditInst<fxcc::graph::common::TextureMaps>("m_Textures_", inst.m_Textures);
	
	if (ImGui::Button("Init Shader"))
	{
		inst.OnShaderChanged();
	}

    return flag;
}
